登录页
<template>
  <div>
    <video src="../../assets/video/EP03.mp4" class="video_a" muted autoplay loop></video>
    <div class="container">

      <el-form :model="loginFrom" status-icon :rules="rules" ref="loginFrom" label-width="100px" class="demo-loginFrom">
        <!-- 开始是二维码角标，点击之后电脑角标，再次点击又切换 -->
        <i @click="changeLoginType" :class="['jiaobiao', 'iconfont', jiaobiaoType]"></i>
        <h1 class="title">{{titlename}}</h1>
        <!-- 常规登录 -->
        <Common @synLoginFrom="handleLoginFrom" @submits="submit" ref="commonLogin" v-if="loginType === 'common'"
          @changeSmsType="changeSmsType"></Common>
        <!-- 二维码登入 -->
        <QrLogin :storageUserInfo="storageUserInfo" v-else-if="loginType === 'qrcode'"></QrLogin>
        <!-- 短信验证码登录 -->
        <SmsLogin :storageUserInfo="storageUserInfo" v-else></SmsLogin>


      </el-form>

    </div>
  </div>
</template>

<script>

import Common from '@/components/Login/RegularLogin'
import QrLogin from '@/components/Login/Two-dimensional-code'
import SmsLogin from '@/components/Login/SMS-login'
import * as api from '@/api/users'
import storage from '@/utils/storage'
//校验验证码
var validateCaptcha = (rule, value, callback) => {
  if (value.length < 5) {
    callback("请输入验证码");
  } else {
    callback();
  }
};
//校验用户名
var validateUsername = (rule, value, callback) => {
  //3-16为字母数字下划线
  var uPattern = /^[a-zA-Z0-9_-]{3,16}$/;
  //如果检验通过，要直接回调callback()
  //如果检验不通过 callback中传参数
  if (uPattern.test(value)) {
    callback();
  } else {
    callback("请输入3-16为字母数字下划线");
  }
};
//校验密码
var validatePassword = (rule, value, callback) => {
  if (value.length < 3) {
    callback("密码长度不能小于3位");
  } else {
    callback();
  }
};

export default {
  data() {
    return {
      //common 常规登录||qrcode 二维码登录||sms 短信登录
      loginType: 'common',//登录方式
      loginFrom: {
        username: "",
        password: "",
        captcha: "",
      },
      titlename:'千峰管理系统',
      rules: {
        username: [{ validator: validateUsername, trigger: "blur" }],
        password: [{ validator: validatePassword, trigger: "blur" }],
        captcha: [{ validator: validateCaptcha, trigger: "blur" }],
      },
    };
  },
  components: {
    Common,
    QrLogin,
    SmsLogin
  },
  computed: {
    jiaobiaoType() {
      if (this.loginType === 'common') {
        return 'icon-erweimajiaobiao'
      }
      if (this.loginType === 'qrcode' || this.loginType === 'sms') {
        return 'icon-diannaojiaobiao'
      }
    }
  },
  methods: {
    changeSmsType() {
      this.loginType = 'sms'
    },
    changeLoginType() {
      if (this.loginType === 'common') {
        this.loginType = 'qrcode'
      } else if (this.loginType === 'qrcode') {
        this.loginType = 'common'
      } else if (this.loginType === 'sms') {
        this.loginType = 'common'
      }
    },
    handleLoginFrom(newLoginFrom) {
      // console.log(newLoginFrom,"123")
      this.loginFrom = newLoginFrom
    },
    submit() {
      // console.log('123')
      // console.log(this.$refs)
      this.$refs['loginFrom'].validate((valid) => {
        //登录
        //1.获取后台的验证码
        //2.进行本地校验
        //3.本地校验通过=>先校验验证码
        //4.验证码通过再校验用户名和密码
        //5.成功和失败
        //本地校验通过
        if (valid) {
          // 本地校验通过
          // alert('submit!');
          api.verifyCaptchaApi(this.loginFrom.captcha)
            .then(async res => {
              // console.log(res)
              if (res.data.state) {
                //验证通过,检验用户名和密码
                let { username, password } = this.loginFrom
                let res = await api.loginApi(username, password)
                // console.log(789,res)
                //登录成功
                if (res.data.state) {
                  //存储用户信息到本地

                  this.storageUserInfo(res.data)
                  //跳转到主页Home
                  this.$router.push('/Home')
                }
              } else {
                //验证不通过 刷新验证码
                this.$refs['commonLogin'].getCaptcha()
              }
            })
        } else {
          // 本地校验不通过
          console.log('error submit!!')
          return false
        }
      })

    },
    //封装一个方法，用于存储用户的信息和token
    storageUserInfo({ userInfo, token, permission }) {
      storage.set('userInfo', userInfo)
      storage.set('qf-token', token)
      storage.set('permission', permission)
    },
  },

};
</script>
<style lang="less" scoped>
/* //修改element-ui的样式
        //1.打开调试器，找准类名，覆盖样式
        //2.看权重，使用!important
        //3.使用深度选择器>>>  /deep/  */


.video_a {
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

.container {
  width: 400px;
  height: 460px;
  background-color: rgba(2, 2, 2, 0.4);
  padding-top: 60px;
  position: fixed;
  // z-index: 999;
  top: 148px;
  right: 48px;
}


.jiaobiao {
  font-size: 60px;
  color: #fff;
  position: absolute;
  right: -1px;
  top: -1px;
  cursor: pointer;
  opacity: 0.7;
}
.title {
    font-size:30px;
    text-align: center;
    margin-bottom:15px;
    color: #fff;
    // background-image: linear-gradient(30deg, #0400ff, #c8e7ea);
    // background-clip: text;
    // -webkit-background-clip: text;
	  // -webkit-text-fill-color: transparent;
    font-weight: 400;
  }
</style>